#include "buff.h"
using namespace Buffer_;
const int prependable = 8;
const int initBufferSize = 1024;
/**
 *      prependable     readableBytes    writeableBytes     capacity
 *  +----------------+---------------------+-------------+............+
 *  |                |                     |             |            |
 *  |                |                     |             |            |
 *  |                |                     |             |            |
 *  +----------------+---------------------+-------------+............+
 *                   ↑                     ↑
 *              RIndex_ptr             WIndex_ptr
 * 
 * 
*/
Buffer::Buffer(int initBufferSize)
        :buffer_(initBufferSize),
        Index_read(prependable),
        Index_write(prependable)
{
}
size_t Buffer::writeToFd(int fd,int *Errnoo)
{
    //向 Fd 中写数据
    //writev?
    int len = write(fd,RIndex_ptr(),readableBytes());
    if(len <0)
    {
        //std::cout<<"write Failed ... "<<std::endl;
        *Errnoo = errno; 
        return len;
    }
    else
    {
        Rmove_RW_Index(Index_read,len);
        return len;
    }
    
}
size_t Buffer::readFromdFd(int fd,int *Errnoo)
{
    //从 Fd 中读数据
    assert(fd>0);
    size_t Writeables  = writeableBytes();
    char buff[65536];
    //将用户数据暂存于堆上的buff //中文呢？
    //readv| iov[0]  <--- iov[1]
    struct iovec /*const*/ io[2];
    //{{WIndex_ptr(),Writeables},{buff,sizeof(buff)}};
    io[0].iov_base = WIndex_ptr();
    io[0].iov_len = Writeables;
    io[1].iov_base = buff;
    io[1].iov_len = sizeof(buff);

    ssize_t len = readv(fd,io,2);

    if(len <= 0) //写入失败
    {
        *Errnoo = errno;
        return len;
    }
    else if(static_cast<size_t>(len) <= Writeables)    //成功写入的大小 小于 剩余空间
    {
        Rmove_RW_Index(Index_write,len);
    }
    else    //buffer_写满了 仍然还不够
    {
        Index_write = buffer_.size();
        
        append(buff,static_cast<size_t>(len - Writeables));
    }
    return len;
}
void Buffer::append(const char *str,size_t size)
{
    assert(str!=nullptr);
    isEnableWrite(size);
    std::copy(str,str+size,WIndex_ptr());
    Rmove_RW_Index(Index_write,size);
}
void Buffer::append(const std::string& str)
{
    append(str.c_str(),strlen(str.c_str()));
}
void Buffer::append(void *str,size_t size)
{
    append(static_cast<const char*>(str),size);
}
void Buffer::append(const Buffer& Buffer_)
{
    append(Buffer_.RIndex_cptr(),Buffer_.readableBytes());
}
size_t Buffer::writeableBytes() const
{
    //可写字节数 = 当前size - 写指针 - 预留的 pend 位
    return (buffer_.size() - Index_write /*- (prependableBytes())*/);
}
void Buffer::isEnableWrite(size_t len)
{
    //写入长度 与 可写长度进行比较
    if(len > writeableBytes())
    {
        move_block(len);
    }
    //assert(len<=writeableBytes());
}
void Buffer::makezero()
{
    bzero(&buffer_[0],buffer_.size());
    Index_read = Index_write = prependableBytes();
}

const char *Buffer::RIndex_cptr() const
{
    return &(buffer_[Index_read]);
    //return &(buffer_.at(Index_read));
}

size_t Buffer::prependableBytes() const
{
    return (prependable);
}
size_t Buffer::readableBytes() const
{
    return (Index_write - Index_read);
}
const char *Buffer::WIndex_cptr() const
{
    return &(buffer_[Index_write]);
}
void Buffer::Rmove_RW_Index(std::atomic<int> & Index,size_t len)
{
    Index +=len;   
}
void Buffer::HasWriten(size_t len)
{
    Rmove_RW_Index(Index_write,len);
}
void Buffer::HasRead(size_t len)
{
    Rmove_RW_Index(Index_read,len);
}
char* Buffer::RIndex_ptr()
{
    return &buffer_[Index_read];
}
char* Buffer::WIndex_ptr()
{
    return &buffer_[Index_write];
}
const char *Buffer::Begin_cptr()
{
    return &buffer_[prependableBytes()];
}
char *Buffer::Begin_ptr()
{
    return &buffer_[prependableBytes()];
}
std::string Buffer::getReadBlock()
{
    std::string str(RIndex_ptr(),WIndex_ptr());
    return str;
}
void Buffer::move_block(size_t size /*length*/)
{
    //优先考虑 能否移动,下策就只能 resize   [  ,  ) 
    if(size > writeableBytes() /*+ 1*/)   //resize
    {
        buffer_.resize(Index_write+ size + 1);
    }
    else    //move
    {
        std::copy(RIndex_ptr(),WIndex_ptr(),Begin_ptr());        
        Index_read = prependableBytes();
        Index_write = Index_read + readableBytes();
    }
}

/*int main()
{
    Buffer buff;
    std::string str;
    buff.append("法国发过合法合规帮帮忙");
    str.append(buff.RIndex_ptr(),buff.WIndex_ptr());
    std::cout<<str<<std::endl;
    return 0;
}*/